package com.zh.webcommon.common.viewdata;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.function.BiFunction;

/**
 * ApiResult的data值不打印完全，为了减少打印日志
 * 返回list时,size超过上限时，只打印数组的size和class type
 */
public class CollectionSummarySerializer extends JsonSerializer<Object> {
    private static final int MAX_ELEMENTS_TO_SHOW = 10;

    static BiFunction<Class<?>, Integer, String> summaryStrFun = (clazz, size) -> String.format("[%s ... (size=%d)]", clazz.getSimpleName(), size);

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }

        // 处理数组
        if (value.getClass().isArray()) {
            int length = Array.getLength(value);
            if (length > MAX_ELEMENTS_TO_SHOW) {
                Object first = Array.get(value, 0);
                gen.writeString(summaryStrFun.apply(first.getClass(), length));
            } else {
                gen.writeStartArray();
                for (int i = 0; i < length; i++) {
                    gen.writeObject(Array.get(value, i));
//                    serializerProvider.defaultSerializeValue(Array.get(value, i), gen);
                }
                gen.writeEndArray();
            }
        }
        // 处理 Collection
        else if (value instanceof Collection<?> collection) {
            if (collection.size() > MAX_ELEMENTS_TO_SHOW) {
                Object first = collection.iterator().next();
                gen.writeString(summaryStrFun.apply(first.getClass(), collection.size()));
            } else {
                gen.writeStartArray();
                for (Object item : collection) {
                    gen.writeObject(item);
//                    serializerProvider.defaultSerializeValue(item, gen);
                }
                gen.writeEndArray();
            }
        }
        // 非集合/数组类型
        else {
//            serializerProvider.defaultSerializeValue(value, gen);
            gen.writeObject(value);
        }

    }
}
